SWAGOLX.EXE (c) 1993 GDSOFT ALL RIGHTS RESERVED 00006 NOVELL/LANTASTIC NETWORK ROUTINES 1 05-28-9313:52ALL SWAG SUPPORT TEAM DETCNETX.PAS IMPORT 13 {π▒i'm trying to find a method by which i can, from within a TP Program,π▒detect whether or not the NetWare shell has been loaded (Net3, NetX, orπ▒whatever); i've figured out how to determine if IPX is running, butπ▒can't seem to nail down the shell; the general idea is to detect IPX,π▒detect the shell, determine whether or not the user is logged in, and ifπ▒not, give them the oppurtUnity to do so; i've got most of the restπ▒figured out, but can't find the shell; any help would be greatlyπ▒appreciatedππTry Interrupt 21h, Function EAh, GetShellVersion;π}ππUsesπ {$IFDEF DPMI}π WinDos;π {$ELSE}π Dos;π {$endIF}πVarπ vOS,π vHardwareType,π vShellMajorVer,π vShellMinorVer,π vShellType,π vShellRevision : Byte;π {$IFDEF DPMI}π vRegs : tRegisters;π {$ELSE}π vRegs : Registers;π {$endIF}ππProcedure GetShellVersion;πbeginπ vOS := 0;π vHardwareType := 0;π vShellMajorVer := 0;π vShellMinorVer := 0;π vShellType := 0;π vShellRevision := 0;π FillChar(vRegs, SizeOf(vRegs), 0);π With vRegs DOπ beginπ AH := $EA;π Intr($21, vRegs);π vOS := AH; (* $00 = MS-Dos *)π vHardwareType := AL; (* $00 = PC, $01 = Victor 9000 *)π vShellMajorVer := BH;π vShellMinorVer := BL;π vShellType := CH; (* $00 = conventional memory *)π (* $01 = expanded memory *)π (* $02 = extended memory *)π vShellRevision := CL;π end;πend;ππbeginπ GetShellVersion;π Writeln(vOS);π Readln;πend. 2 05-28-9313:52ALL SWAG SUPPORT TEAM GET-ID1.PAS IMPORT 24 { TS> Can anybody help me finding the interrupt For gettingπ TS> a novell current user_name and the current station adress ??π}πProcedure GetConnectionInfoπ(Var LogicalStationNo: Integer; Var Name: String; Var HEX_ID: String;π Var ConnType : Integer; Var DateTime : String; Var retcode:Integer);ππVarπ Reg : Registers;π I,X : Integer;π RequestBuffer : Recordπ PacketLength : Integer;π FunctionVal : Byte;π ConnectionNo : Byte;π end;π ReplyBuffer : Recordπ ReturnLength : Integer;π UniqueID1 : Packed Array [1..2] of Byte;π UniqueID2 : Packed Array [1..2] of Byte;π ConnType : Packed Array [1..2] of Byte;π ObjectName : Packed Array [1..48] of Byte;π LoginTime : Packed Array [1..8] of Byte;π end;π Month : String[3];π Year,π Day,π Hour,π Minute : String[2];ππbeginπ With RequestBuffer Do beginπ PacketLength := 2;π FunctionVal := 22; { 22 = Get Station Info }π ConnectionNo := LogicalStationNo;π end;π ReplyBuffer.ReturnLength := 62;π With Reg Do beginπ Ah := $e3;π Ds := Seg(RequestBuffer);π Si := ofs(RequestBuffer);π Es := Seg(ReplyBuffer);π Di := ofs(ReplyBuffer);π end;π MsDos(Reg);π name := '';π hex_id := '';π connType := 0;π datetime := '';π if Reg.al = 0 then beginπ With ReplyBuffer Do beginπ I := 1;π While (I <= 48) and (ObjectName[I] <> 0) Do beginπ Name[I] := Chr(Objectname[I]);π I := I + 1;π end { While };π Name[0] := Chr(I - 1);π if name<>'' thenπ beginπ Str(LoginTime[1]:2,Year);π Month := Months[LoginTime[2]];π Str(LoginTime[3]:2,Day);π Str(LoginTime[4]:2,Hour);π Str(LoginTime[5]:2,Minute);π if Day[1] = ' ' then Day[1] := '0';π if Hour[1] = ' ' then Hour[1] := '0';π if Minute[1] = ' ' then Minute[1] := '0';π DateTime := Day+'-'+Month+'-'+Year+' ' + Hour + ':' + Minute;π end;π end { With };π end;π retcode := reg.al;π if name<>'' thenπ beginπ hex_id := '';π hex_id := hexdigits[replybuffer.uniqueid1[1] shr 4];π hex_id := hex_id + hexdigits[replybuffer.uniqueid1[1] and $0F];π hex_id := hex_id + hexdigits[replybuffer.uniqueid1[2] shr 4];π hex_id := hex_id + hexdigits[replybuffer.uniqueid1[2] and $0F];π hex_id := hex_id + hexdigits[replybuffer.uniqueid2[1] shr 4];π hex_id := hex_id + hexdigits[replybuffer.uniqueid2[1] and $0F];π hex_id := hex_id + hexdigits[replybuffer.uniqueid2[2] shr 4];π hex_id := hex_id + hexdigits[replybuffer.uniqueid2[2] and $0F];π ConnType := replybuffer.connType[2];π { Now we chop off leading zeros }π While hex_id[1]='0' do hex_id := copy(hex_id,2,length(hex_id));π end;πend; { GetConnectInfo };ππ 3 05-28-9313:52ALL SWAG SUPPORT TEAM GET-ID2.PAS IMPORT 19 {π> Okay, here goes. I am using Borland Pascal 7.0 under MS-Dos 5.0.π>Basically, the Program I am writing will be run under Novell Netwareπ>3.11. What I need to do is determine the User's full user name. Iπ>could do this using Novell Interrupts, but they are impossible to figureπ>out (At least For me). So what I wanted to do, was use Novell'sπ>"WHOAMI" command. What this does is return the user's full name andππWell, I think you'll find it harder to to a Dos exec and parse the output afterπreading it from a File than asking Netware what it is. Plus you must depend onπthe user having access to use the command. I'm on some Novell networks whereπthat command File is not present because it wasn't considered important.πHere's how to get the user name from Netware...π}πProgram UserID;ππUsesπ Dos, Strings;ππTypeπ RequestBuf = Recordπ RequestLen : Word; { Number of Bytes in the rest of the Record }π SubFunction : Byte; { Function from Novell we are requesting }π ConnectionNum : Byte; { Connection number that is making the call }π end;ππ ReplyBuf = Recordπ ReplyLength : Word; { Number of Bytes in the rest of the Record }π ObjectId : LongInt; { Novell refers to everything by Objects like users}π ObjectType : Word;π ObjectName : Array[1..48] of Char;π LoginTime : Array[1..7] of Char;π end;ππVarπ I:Word;π ReqBuf : RequestBuf;π RepBuf : ReplyBuf;π Regs : Registers;π UserName : String[48];ππbeginπ Regs.AH := $DC;π MsDos(Regs); { Get the connection number }ππ ReqBuf.RequestLen := 2; { User ID request, must give connection }π ReqBuf.SubFunction := $16; { number }π ReqBuf.ConnectionNum := Regs.AL;ππ RepBuf.ReplyLength := 61; { Return buffer For name }ππ Regs.AH := $E3; { Call Novell For user name }π Regs.DS := Seg(ReqBuf); { Passing it the request buffer indicating }π Regs.SI := Ofs(ReqBuf); { the data we want and a reply buffer to send }π Regs.ES := Seg(RepBuf); { us back the information }π Regs.DI := Ofs(RepBuf);π MsDos(Regs);ππ { Object name now contians the users ID, use the StringS Unit Functions }π { to print the null-terminated String }π WriteLn(StrPas(@RepBuf.ObjectName));πend.ππ{πThat will read in a Novell User ID For you.π}π 4 05-28-9313:52ALL SWAG SUPPORT TEAM GET-ID3.PAS IMPORT 22 {π[ Does anyone know the syntax For Novell-specific interrupts in Pascalπ[(or C)? I have posted this message in all the pascal confs nad haven'tπ[had any replies. Any help is appreciated.π[ Specifically, I need to use interrupts to find the username, securityπ[in a certain directory and groups belongs to.ππSince this is Novell-specific I hope the moderator won't mind if Iπanswer this one in this conference, rather than Pascal conf...ππYou Absolutely NEED a copy of "System Calls - Dos" from Novell. Thisπbook has every last call you'll ever need For getting inFormation out ofπNetWare. Warning: some of their inFormation is erroneous, and you'llπjust have to do things like count up the size of the Reply buffers, Forπexample, and not trust their reported Record sizes.ππJust as an example of how to use the inFormation from the System Callsπbook, here's an example of a Function I slapped together to return aπ3-Character username. Pretty much all the Novell calls work the sameπway: you set up a Request buffer and a Reply buffer, then you read yourπresults into whatever Format you want them. Hope this helps:π}ππFunction GetNetUserID:String;πVarπ NovRegs:Registers;π Answer:String[3];π iii:Integer;π ConnectNo:Byte;π Request : Recordπ Len : Word; {LO-HI}π SubF : Byte;π ConnNum: Word; {HI-LO}π end;π Reply : Recordπ Len : Word; {LO-HI}π ObjID : LongInt; {HI-LO}π ObjType: Word;π ObjName: Array[1..48] of Byte;π LogTime: Array[1..7] of Byte;π end;πbeginπ if (ReqdNetType <> Novell) thenπ GetNetUserID := copy(ParamStr(2),1,3);π if (ReqdNetType = Novell) thenππ beginππ With NovRegs doπ beginπ AH := $dc;π AL := $00;π cx := $0000;π end;ππ MsDos(NovRegs);π ConnectNo:=NovRegs.AL;ππ For iii := 1 to 48 doπ beginπ Reply.ObjName[iii] := $00;π end;ππ With Request doπ beginπ Len := Sizeof(Request) - 2;π SubF := $16;π ConnNum:= (ConnectNo);π end;ππ Reply.Len := Sizeof(Reply) - 2;ππ With NovRegs doπ beginπ AH := $e3;π DS := Seg(Request);π SI := ofs(Request);π ES := Seg(Reply);π DI := ofs(Reply);π end;ππ MsDos(NovRegs);π Answer:=' ';ππ For iii:= 1 to 3 doπ beginπ Answer[iii]:= chr(Reply.ObjName[iii]);π end;ππ GetNetUserID:= Answer;π end;πend; {GetNetUserID}ππ{πThat $e3 in the AH register is the generic bindery call. $16 is theπsubFunction For "Get Connection Name" in the Bindery calls.π}π 5 05-28-9313:52ALL SWAG SUPPORT TEAM ISFILOPN.PAS IMPORT 4 Varπ Fi : File;ππFunction ISOpen(Var Fil:File):Boolean;π(* Returns True is File has is open ON A NETWORK!!! *)πVarπ P:^Byte;πbeginπ P:=@Fil;π If P^=0 then IsOpen:=False else IsOpen:=True;πend;ππbeginπ Assign(Fi,'FileOPEN.PAS');π Writeln(ISOpen(Fi));πend. 6 05-28-9313:52ALL SWAG SUPPORT TEAM LOCKREC.PAS IMPORT 15 {πThe following Program is a slight modification of one posted by ZachπLinnet. The problem is it doesn't lock the use of the File and allowsπmultiple PC's to access the File at the same time. Also, it seems toπtake input from the keyboard when it isn't supposed to and I am unableπto locate why. How could I improve this to actually lock the File?πWhat if I just wanted to lock one or two Records?π}ππProgram Sample_File_Locking_Program;πUsesπ Crt;πTypeπ Fi = File of Integer;πVarπ FileName : String;π f : Fi;π x, n : Integer;π Choice : Char;ππbeginπ {$I-}π FileName := 'e:\test\test.dat';π Assign(f,FileName);π Repeatπ Write('Option [rwq] ? '); choice := ReadKey;π Writeln(choice);π Case choice ofπ 'r' : beginπ Writeln('Attempting to read : ');π Reset(f);π While Ioresult <> 0 doπ beginπ Writeln('Busy waiting...');π Reset(f);π end;π Write('Reading now...');π For x := 1 to 1000 doπ Read(f,n);π Writeln('done!');π Close(f);π end;π 'w' : beginπ Writeln('Attempting to Write : ');π Reset(f);π if Ioresult = 2 thenπ ReWrite(f);π While Ioresult <> 0 doπ beginπ Writeln('Busy waiting...');π Reset(f);π end;π Write('Writing now...');π For x := 1 to 1000 doπ Write(f,x);π Writeln('done!');π Close(f);π end;π end; { Case }π Until Choice = 'q';π {$I+}πend.π